<template>
  <openlayer-base-map ref="refOpenlayerBaseMap" :currentPageType="'gis'" @getOlMapInstance="getOlMapInstance"
    @getCurrentViewData="getCurrentViewData" @reflashMap="reflashMap">
    <!-- 搜索组件 -->
    <map-search />

    <!-- 右侧信息 - 健康度概览 -->
    <health-overview />
  </openlayer-base-map>
</template>

<script setup>
// vue - core
import { ref } from "vue";
import { useRoute } from "vue-router";
// 组件
import OpenlayerBaseMap from "@/components/OpenlayerBaseMap/index.vue";
import MapSearch from "./components/map-search/index.vue"; // 搜索组件
import HealthOverview from "./components/HealthOverview.vue"; // 健康度概览
import { getPopupInnerDom, getFeaturesPopupInnerDom } from "./components/popup/gisPopup"; // 气泡窗dom
// 工具
import mittBus from "@/utils/mittBus"; // mitt - 组件传参工具
// api相关 - 工具
import { apiCommon, objIsEmpty } from "@/utils/index.js";
import * as gisApi from "@/api/gis/gis";

const { proxy } = getCurrentInstance();

// 路由相关
const route = useRoute();

// 地图相关
const refOpenlayerBaseMap = ref(null); // 地图核心元素
let myOlMap = null;
let myMapCommonData = null;

// 业务数据
let currentContactType = "all"; // 当前网络制式
let currentCoverType = "all"; // 当前基站类型
let currentRenderType = "频率"; // 当前渲染方式

// 路由跳转参数
// let queryObj = null;  // 需要全局使用时解开

/**
 * 接收路由跳转参数
 */
const getQuery = () => {
  // 判断是否有参数
  if (objIsEmpty(route.query)) {
    return;
  }

  const { cgi } = route.query;

  // 根据cgi查询
  searchByCGIAsync(cgi); // 根据cgi搜索详情
};

/**
 * 接收其他组件派发的方法
 */
/**
 * 气泡窗
 */
//  修改通用展示窗数据
mittBus.on("fixCommonPopupData", (popupObj) => {
  // console.log("修改通用展示窗数据", popupObj);

  switch (popupObj.popupData.networkType) {
    case "4g":
      popupObj.popupData.newCellName = popupObj.popupData.cellName;
      break;
    case "5g":
      popupObj.popupData.newCellName = popupObj.popupData.nrCellName;
      break;
  }
});
// 设置通用气泡窗html
mittBus.on("setCommonPopupInner", ({ popupObj, callback }) => {
  // console.log("设置通用气泡窗html", popupObj);

  callback(getPopupInnerDom(popupObj));
});
// 设置重叠要素气泡窗html
mittBus.on('setFeaturesPopupInner', ({ popupObj, callback, next }) => {
  // console.log(popupObj, callback)

  callback(getFeaturesPopupInnerDom(popupObj, currentDataList => {
    next(currentDataList)
  }));
})
//  气泡窗点击更多 - 子组件使用
mittBus.on("popupDataGetMore", async ({ currentPopupObj, callback }) => {
  // console.log("气泡窗点击更多", currentPopupObj);

  // 或者走接口,根据cgi获取详情
  const currentPopupAsyncObj = await apiCommon(gisApi.queryCellByCgi, {
    cgi: currentPopupObj.popupData.cgi,
  });

  switch (currentPopupAsyncObj.data.networkType) {
    case "4g":
      currentPopupObj.popupData = currentPopupAsyncObj.data.cell4g;
      currentPopupObj.popupData.networkType = "4g";
      currentPopupObj.popupData.newCellName =
        currentPopupObj.popupData.cellName;
      break;
    case "5g":
      currentPopupObj.popupData = currentPopupAsyncObj.data.cell5g;
      currentPopupObj.popupData.networkType = "5g";
      currentPopupObj.popupData.newCellName =
        currentPopupObj.popupData.nrCellName;
      break;
  }

  // 获取完数据后进行弹窗
  callback(currentPopupObj.popupData);
});

/**
 * 业务相关
 */
// 获取网络制式
mittBus.on("getContactType", (val) => {
  // console.log("获取网络制式", val, myOlMap)

  currentContactType = val;

  reflashCurrentMapByType(); // 根据类型刷新当前可视区域地图
});
// 查询基站类型
mittBus.on("getCoverType", (val) => {
  // console.log("查询基站类型", val, myOlMap)

  currentCoverType = val;

  reflashCurrentMapByType(); // 根据类型刷新当前可视区域地图
});
// 切换渲染方式
mittBus.on("setRenderType", (val) => {
  // console.log("切换渲染方式", val, myOlMap);

  currentRenderType = val;

  reflashCurrentMapByType();
});
// 加载kml
mittBus.on("loadKML", (text) => {
  // console.log('加载kml', text, myOlMap)

  refOpenlayerBaseMap.value.loadKML(myOlMap, text);

  // 加载当前4g5g
  currentCoverType = undefined;
  currentContactType = "all";
  isRemoveMap.value = false;
  reflashCurrentMapByType(); // 根据类型刷新当前可视区域地图

  // 通知弹窗关闭
  mittBus.emit("closeLoadKfmlFileDialog");
});

/**
 * 图层管理
 */
// 选择默认图层
mittBus.on("selectDefaultLayer", (val) => {
  // console.log("selectDefaultLayer", val)

  currentCoverType = undefined;
  let currentType = "";

  if (val.length === 0) {
    refOpenlayerBaseMap.value.removeAllLayer(myOlMap); // 移除所有图层
  }

  if (val.length === 1) {
    switch (val[0]) {
      case "LTE资源":
        currentType = "4g";
        break;
      case "5G资源":
        currentType = "5g";
        break;
    }
    currentContactType = currentType;
    reflashCurrentMapByType();
  }

  if (val.length === 2) {
    currentContactType = "all";
    reflashCurrentMapByType();
  }
});

/**
 * 网格管理
 */
// 选择网格
mittBus.on("selectGrid", (gridData) => {
  // console.log(gridData);
  let { centerCoordinates, polygonCoordinates } = gridData;
  // console.log(centerCoordinates, centerCoordinates);

  myOlMap.getView().setZoom(myOlMap.getView().getMinZoom()); // 修改至最小zoom

  refOpenlayerBaseMap.value.removeLayerByType(myOlMap, "Polygon"); // 根据类型移除图层

  // 调用函数飞到指定的坐标
  refOpenlayerBaseMap.value.flyToCoordinate(myOlMap, centerCoordinates);

  // 创建多边形
  refOpenlayerBaseMap.value.createPolygon(
    myOlMap,
    polygonCoordinates,
    gridData,
    (feature) => {
      // console.log("创建多边形后操作", feature);

      let polygonCenter = refOpenlayerBaseMap.value.getPolygonCenter(feature);
      gridData.polygonCenter = polygonCenter;

      refOpenlayerBaseMap.value.addTextPoint(myOlMap, gridData.name, gridData.polygonCenter, { tempType: 'gridLabel' }, (layerItem, currentFeature) => {
        // console.log(currentFeature)

        if (currentFeature.get('tempType') === 'gridLabel') {
          // console.log(layerItem)
          myOlMap.removeLayer(layerItem)
        }
      });
    },
    refOpenlayerBaseMap.value.setFeaturesStyle(
      "rgba(255, 255, 255, 0.8)",
      "#e4e7ed"
    )
  );
});

/**
 * gisSubmit循环派发事件
 */
// 根据cgi搜索
mittBus.on("searchByCGI", async (cgi) => {
  // console.log('根据cgi搜索', cgi)

  searchByCGIAsync(cgi); // 根据cgi搜索详情
});
// 根据小区名称搜索
mittBus.on("searchByCellName", async (cellName) => {
  // console.log('根据小区名称搜索', cellName)

  let params = {
    cellName,
  };
  let gisData = await apiCommon(gisApi.queryCellListByCellName, params);
  gisData = gisData.data;
  // console.log(gisData)

  // 如果只有一条数据
  if (gisData.length === 1) {
    searchByCGIAsync(gisData[0].cgi); // 根据cgi搜索详情
  }
});
// 根据站点名称搜索
mittBus.on("searchByStationName", async (stationName) => {
  console.log("根据站点名称搜索", stationName);

  let params = {
    stationName,
  };
  let gisData = await apiCommon(gisApi.queryCellListByStationName, params);
  gisData = gisData.data;
  // console.log(gisData)

  // 如果只有一条数据
  if (gisData.length === 1) {
    searchByCGIAsync(gisData[0].cgi); // 根据cgi搜索详情
  }
});
// 搜索框下拉选择
mittBus.on("selectGisSearchSubmit", (val) => {
  searchByCGIAsync(val.cgi); // 根据cgi搜索详情
});

/**
 * 扩展地图封装方法
 */
// 根据频率渲染扇形
const renderCurveByFrequency = (curveData, optity = 0.4) => {
  // console.log("根据频率渲染扇形");

  let myCurveStyle = null; // 扇区样式
  let myStrokeColor = "rgba(255, 205, 67, 0.3)";
  let myCurveRadius = 0; // 扇区半径

  /**
   * 根据频率获取数据
   *
   * A频段  100  填充: rgba(200, 22, 100, 0.4)   线:
   * D频段  110  填充: rgba(55, 33, 188, 0.4)   线:
   * E频段  120  填充: rgba(88, 99, 200, 0.4)   线:
   * F频段  130  填充: rgba(255, 255, 0, 0.4)   线:
   * FDD  140   填充:  rgba(255, 76, 127, 0.4)  线:
   * 其他  150  填充:  rgba(32, 222, 230, 0.4)   线 : rgba(255, 205, 67, 0.3)
   */
  switch (curveData.workFrequency) {
    case "A频段":
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(200, 22, 100, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 100;
      break;
    case "D频段":
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(55, 33, 188, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 110;
      break;
    case "E频段":
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(88, 99, 200, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 120;
      break;
    case "F频段":
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(255, 255, 0, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 130;
      break;
    case "FDD":
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(255, 76, 127, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 140;
      break;
    default:
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(32, 222, 230, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 150;
      break;
  }

  return { myCurveStyle, myCurveRadius };
};

// 根据健康度渲染扇形
const renderCurveByHealth = (curveData, optity = 0.4) => {
  // console.log("根据健康度渲染扇形");

  let myCurveStyle = null; // 扇区样式
  let myStrokeColor = "rgba(255, 205, 67, 0.3)";
  let myCurveRadius = 0; // 扇区半径

  /**
   * 根据频率获取数据
   *
   * A频段  100  填充: rgba(200, 22, 100, 0.4)   线:
   * D频段  110  填充: rgba(55, 33, 188, 0.4)   线:
   * E频段  120  填充: rgba(88, 99, 200, 0.4)   线:
   * F频段  130  填充: rgba(255, 255, 0, 0.4)   线:
   * FDD  140   填充:  rgba(255, 76, 127, 0.4)  线:
   * 其他  150  填充:  rgba(32, 222, 230, 0.4)   线 : rgba(255, 205, 67, 0.3)
   */
  switch (curveData.workFrequency) {
    case "A频段":
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(200, 22, 100, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 100;
      break;
    case "D频段":
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(55, 33, 188, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 110;
      break;
    case "E频段":
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(88, 99, 200, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 120;
      break;
    case "F频段":
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(255, 255, 0, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 130;
      break;
    case "FDD":
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(255, 76, 127, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 140;
      break;
    default:
      myCurveStyle = refOpenlayerBaseMap.value.setFeaturesStyle(
        `rgba(32, 222, 230, ${optity})`,
        myStrokeColor
      );
      myCurveRadius = 150;
      break;
  }

  return { myCurveStyle, myCurveRadius };
};

// 根据字段渲染扇形
const renderCurveByField = (curveData, optity = 0.4) => {
  switch (currentRenderType) {
    case "频率":
      return renderCurveByFrequency(curveData, (optity = 0.4));
    case "健康度":
      return renderCurveByHealth(curveData, (optity = 0.4));
  }
};

// 根据数据渲染Feature
const renderFeatureByData = (olMap, dataList) => {
  // console.log("根据数据渲染Feature");
  refOpenlayerBaseMap.value.renderFeatureByData(
    olMap,
    dataList,
    (olMap, item) => {
      // console.log(olMap, item);
      // console.log(item);
      if (item.coverType === "室内") {
        let innerPoint = [];
        innerPoint.push({
          lonlat: [item.longitude, item.latitude],
          pointData: item,
        });

        // 批量添加点
        refOpenlayerBaseMap.value.addPoint(olMap, innerPoint);
      }

      if (item.coverType === "室外") {
        // console.log(item.workFrequency)

        let outPoint = [];
        outPoint.push({
          lonlat: [item.longitude, item.latitude],
          // 需要有antDirectionAngle字段
          curveData: item,
        });
        // 批量添加扇形
        refOpenlayerBaseMap.value.addCurve(olMap, outPoint, (item) => {
          return renderCurveByField(item.curveData);
        });
      }
    }
  );
};

// 通过单条数据设置地图
const setMapBySingleData = (olMap, itemData) => {
  // console.log('通过单条数据设置地图', olMap, itemData)

  refOpenlayerBaseMap.value.setMapBySingleData(
    olMap,
    itemData,
    (itemData) => {
      switch (itemData.networkType) {
        case "4g":
          itemData.newCellName = itemData.cellName;
          break;
        case "5g":
          itemData.newCellName = itemData.nrCellName;
          break;
      }
    },
    (olMap, dataList) => {
      renderFeatureByData(olMap, dataList);
    }
  );
};

/**
 * 封装工具
 */
// gis通用接口封装
const gisDataAsync = async (params, next, isMerge) => {
  let gisData = await apiCommon(gisApi.queryGisList, params);
  gisData = gisData.data;

  if (gisData.cell4gList) {
    gisData.cell4gList.forEach((item) => {
      item.networkType = "4g";
    });
  }

  if (gisData.cell5gList) {
    gisData.cell5gList.forEach((item) => {
      item.networkType = "5g";
    });
  }

  if (isMerge) {
    next([...gisData.cell4gList, ...gisData.cell4gList]);
  } else {
    next(gisData);
  }
};

// 获取可视区域坐标参数
const getCurrentPositionParams = (olMap) => {
  let viewPosition = refOpenlayerBaseMap.value.getCurrentViewPosition(olMap);
  // console.log("获取可视区域的左上角和右下角坐标", viewPosition)

  return {
    minLatitude: viewPosition.bottomRight[1],
    maxLatitude: viewPosition.topLeft[1],
    minLongitude: viewPosition.topLeft[0],
    maxLongitude: viewPosition.bottomRight[0],
    // networkType: "all",
  };
};

// 根据cgi搜索详情
const searchByCGIAsync = async (cgi) => {
  let params = {
    cgi,
  };

  let gisData = await apiCommon(gisApi.queryCellByCgi, params);

  if (!gisData.data) {
    // console.log(gisData.msg);
    proxy.$modal.msgError(gisData.msg);
  } else {
    gisData = gisData.data;
    // console.log(gisData);
  }

  switch (gisData.networkType) {
    case "4g":
      gisData.cell4g.networkType = "4g";
      setMapBySingleData(myOlMap, gisData.cell4g);
      break;
    case "5g":
      gisData.cell5g.networkType = "5g";
      setMapBySingleData(myOlMap, gisData.cell5g);
      break;
  }
};

// 根据类型刷新当前可视区域地图
const reflashCurrentMapByType = (setSingleData) => {
  // console.log("44422", currentContactType, currentCoverType);

  if (myOlMap.getView().getZoom() < myMapCommonData.minRenderZoom) {
    proxy.$modal.msgWarning(
      `为减少卡顿,请在缩放等级大于等于${myMapCommonData.minRenderZoom}的时候进行刷新`
    );
    return;
  }

  let params = {
    ...getCurrentPositionParams(myOlMap),
    networkType: currentContactType,
    coverType: currentCoverType === "all" ? undefined : currentCoverType,
  };
  // console.log(params)

  gisDataAsync(params, (gisDataList) => {
    const { cell4gList, cell5gList } = gisDataList;
    // console.log(cell4gList, cell5gList);

    // 加载数据
    switch (currentContactType) {
      case "4g":
        renderFeatureByData(myOlMap, cell4gList);
        break;
      case "5g":
        renderFeatureByData(myOlMap, cell5gList);
        break;
      default:
        renderFeatureByData(myOlMap, [...cell4gList, ...cell5gList]);
        break;
    }

    if (setSingleData) {
      // 设置被选中的单条数据
      setSingleData();
    }
  });

  /* if (next) {
    next();
  } */
};

/**
 * 业务方法
 */
// 获取地图实例 - 地图加载完初始化做的一些操作[业务相关]
const getOlMapInstance = (olMap, mapCommonData) => {
  // console.log("获取地图实例 - 地图加载完初始化做的一些操作[业务相关]", olMap);

  // console.log(olMap, mapCommonData);

  myOlMap = olMap; // 赋值全局变量,为后续业务操作做准备

  myMapCommonData = mapCommonData;

  // 接收路由跳转参数
  getQuery();
};

// 获取可视区域数据 (主入口)
const getCurrentViewData = (olMap) => {
  let params = {
    ...getCurrentPositionParams(olMap),
    networkType: "all",
  };
  // console.log(params);

  gisDataAsync(params, (gisDataList) => {
    // console.log(gisDataList);
    const { cell4gList, cell5gList } = gisDataList;
    renderFeatureByData(olMap, cell4gList);
    renderFeatureByData(olMap, cell5gList);
  });
};

// 刷新地图 - 主入口方法
const reflashMap = (resetFlag, next) => {
  // console.log("刷新地图", resetFlag);

  if (Boolean(resetFlag)) {
    currentCoverType = undefined;
    currentContactType = "all";
  }

  // 根据类型刷新当前可视区域地图
  reflashCurrentMapByType(() => {
    // 如果刷新后需要进行其他操作
    if (next) {
      next();
    }
  });
};
</script>
